﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace ConstantCMapEditor3
{
    public class NormalSprite : Declaration
    {
        TextSprite spriteTxt;
        String _resourceName;
        TextSprite mirrorButton;

        private bool lockat32;
        public bool LockAt32 
        {
            get
            {
                return lockat32;
            }
            set
            {
                if (value)
                {
                    if (sprite != null)
                    {
                        lockat32 = true;
                        Position = Position;
                    }
                }
                else
                {
                    Position = sprite.Position;
                }
                lockat32 = value;
            }
        }
        bool mirror = false;


        //讀取資源與命名
        public NormalSprite(String ResourceName)
        {
            _resourceName = ResourceName;
            Texture2D texture =ResourceManager.LoadFromFileContent(ResourceName);
            LockAt32 = true;
            sprite = new Sprite(IntelligentTexture.ConvertTexture2DToIntelligent(texture));
            sprite.UserData = this;
            spriteTxt = new TextSprite();
            mirrorButton = new TextSprite();
        }

        override public void InstanceInit()
        {
            NormalSprite box = new NormalSprite(_resourceName);
            box.InstanceReal(this);
        }

        private void InstanceReal(NormalSprite Candidate)
        {
            sprite.TouchEvent += MouseEvent;
            spriteTxt.Text = "Selected: ";
            spriteTxt.Text += ClassID = "sprite" + DateTime.Now.Second + DateTime.Now.Millisecond + Game1.declarationList.Count;
            spriteTxt.Position = new Vector2(spriteTxt.Width / 2 + 50, spriteTxt.Height / 2 + 200);
            spriteTxt.SpriteColor = Color.Green;
            Game1.lineHolderList.Add(this);
            Game1.declarationList.Add(this);
            Game1.SpriteEditorScene.GetCurrentLayer().AttachChild(sprite);
            sprite.Touchable = true;
            DeclarationDeocrator.SetFourRotationButton(this, spriteTxt, 0, 100);
            DeclarationDeocrator.ChangeColorButton(spriteTxt, sprite, 0, 220);
            DeclarationDeocrator.SetLockAt32Button(spriteTxt,this,0,250);
            DeclarationDeocrator.ChangeRenameButton(spriteTxt, this, 0, 280);
            

            _positionChecker = Game1.SpriteEditorScene.GetCurrentChecker();
            _layerName = Game1.SpriteEditorScene.LayerEditState.ToString();
            spriteTxt.Touchable = true;


            mirrorButton.Touchable = true;
            spriteTxt.AttachChild(mirrorButton);
            mirrorButton.Position = new Vector2(0, 200);
            mirrorButton.TouchEvent += ChangeMirror;
            mirrorButton.SpriteColor = Color.Blue;

        }

        public void ChangeMirror(MouseEvent e, Scene s)
        {
            if (e.ClickDownEdgeL)
            {
                Game1.commandManager.Execute(new MirrorCommand(this));

            }
        }

        public void ChangeMirrorState()
        {
            if (mirror) SetNormal();
            else SetMirror();
        }


        public void SetMirror()
        {
            Console.WriteLine("mirror!!");
            mirror = true;
            sprite.SprteEffect = SpriteEffects.FlipVertically;
        }

        public void SetNormal()
        {
            Console.WriteLine("no mirror...");
            mirror = false;
            sprite.SprteEffect = SpriteEffects.None;
        }


        public bool Mirror
        {
            get 
            {
                return mirror;
            }
            set 
            {
                if (value)
                {
                    SetMirror();
                }
                else 
                {
                    SetNormal();
                }
            }

        }

        public void DeleteWithoutCommandManager() 
        {
            Command DeleteCommand = new DeleteSpriteCommand(this, Game1.lineHolderList, Game1.declarationList, Game1.SpriteEditorScene.GetCurrentLayer(), _positionChecker);
            DeleteCommand.Do();
        }

        public void Delete()
        {
            if (!Game1.IsSelecting || !Game1.WorkSpaceLock)
            {
                Command DeleteCommand = new DeleteSpriteCommand(this, Game1.lineHolderList, Game1.declarationList, Game1.SpriteEditorScene.GetCurrentLayer(), _positionChecker);
                Game1.commandManager.Execute(DeleteCommand);
            }
        }

        public Command GetDeleteCommand() 
        {
            if (!Game1.IsSelecting || !Game1.WorkSpaceLock)
            {
                Command DeleteCommand = new DeleteSpriteCommand(this, Game1.lineHolderList, Game1.declarationList, Game1.SpriteEditorScene.GetCurrentLayer(), _positionChecker,false);
                return DeleteCommand;
             }

            return null;
        }

        public Command GetSelectDeleteCommand()
        {
            if (!Game1.IsSelecting || !Game1.WorkSpaceLock)
            {
                Command DeleteCommand = new DeleteSpriteCommand(this, Game1.lineHolderList, Game1.declarationList, Game1.SpriteEditorScene.GetCurrentLayer(), _positionChecker, true);
                return DeleteCommand;
            }

            return null;
        }

        private PositionChecker _positionChecker;
        private String _layerName;

        override public void CandidateInit()
        {
            _positionChecker = Game1.SpriteEditorScene.GetCurrentChecker();
            _layerName = Game1.SpriteEditorScene.LayerEditState.ToString();
            Position = new Vector2(sprite.Width / 2 + 50, sprite.Height / 2 + 50);

            spriteTxt.Text = ClassID = _resourceName;
            spriteTxt.Position = new Vector2(spriteTxt.Width / 2 + 0, spriteTxt.Height / 2 + 0);
            spriteTxt.SpriteColor = Color.Green;
            sprite.Touchable = false;

            
            _positionChecker.UnRegisterPosition(prePosition);
        }


        Vector2 Dif;
        //產生後被點到
        private void MouseEvent(MouseEvent mouseEvent, Scene sender)
        {

            if (mouseEvent.ClickDownEdgeL)
            {
                Game1.Selected = this;
                Dif = new Vector2(0, 0);
            }

            if (mouseEvent.ClickUpEdgeL) 
            {
                Command c = new MoveCommand(this, Dif);
                c.Undo();
                Game1.commandManager.Execute(c);
            }


            if (!Game1.IsSelecting ||!Game1.WorkSpaceLock)
            {
                if (mouseEvent.PressedL)
                {
                    Position += mouseEvent.Position - mouseEvent.PrePosition;
                    Dif += mouseEvent.Position - mouseEvent.PrePosition;
                }
            }


            if (mouseEvent.PressedM)
            {
                Game1.CoordinateScene.Position += mouseEvent.Position - mouseEvent.PrePosition;
            }

            if (KeyBoardManager.IsKeyEdgeDown(Keys.PageUp) && Game1.CoordinateScene.Scale > 0.5f) Game1.CoordinateScene.Scale -= 0.1f;
            if (KeyBoardManager.IsKeyEdgeDown(Keys.PageDown)) Game1.CoordinateScene.Scale += 0.1f;
            if (KeyBoardManager.IsKeyEdgeDown(Keys.Home)) Game1.CoordinateScene.Scale = 1.0f;


        }

        override public bool ReadBack(String str)
        {
            if (str.Contains("PhysicalFactory.SetSpriteOnGameScene"))
            {
                if (str.Contains("Layer1")) 
                {
                    Game1.SpriteEditorScene.LayerEditState = LayerState.Layer1;
                }
                else if (str.Contains("Layer2"))
                {
                    Game1.SpriteEditorScene.LayerEditState = LayerState.Layer2;
                }
                else if (str.Contains("Layer3"))
                {
                    Game1.SpriteEditorScene.LayerEditState = LayerState.Layer3;
                }
                else if (str.Contains("Layer4"))
                {
                    Game1.SpriteEditorScene.LayerEditState = LayerState.Layer4;
                }
                else if (str.Contains("Layer5"))
                {
                    Game1.SpriteEditorScene.LayerEditState = LayerState.Layer5;
                }
                else 
                {
                    Game1.SpriteEditorScene.LayerEditState = LayerState.Layer2;
                }



                String[] temp;
                temp = str.Split(", )".ToCharArray());

                NormalSprite box = new NormalSprite(temp[11].Replace('"', ' ').Trim()+".png");
                box.InstanceReal(this);

                //Get Property
                box.ClassID = temp[1];

                int X = Convert.ToInt32(temp[5]);
                int Y = Convert.ToInt32(temp[7]);
                double R = Convert.ToDouble(temp[9].Replace('f', ' '));


                int ColorR = 255;
                int ColorG = 255;
                int ColorB = 255;
                int ColorA = 255;

                try
                {
                    ColorR = Convert.ToInt32(temp[14].Split("(".ToCharArray())[1]);
                    ColorG = Convert.ToInt32(temp[16]);
                    ColorB = Convert.ToInt32(temp[18]);
                    ColorA = Convert.ToInt32(temp[20]);
                }
                catch 
                {
                    ColorR = 255;
                    ColorG = 255;
                    ColorB = 255;
                    ColorA = 255;
                }

                if (str.Contains("unlock")) box.LockAt32 = false;
                else box.LockAt32 = true;
                
                box.Position = new Vector2(X, Y);
                box.RotateR = (float)R;
                box.sprite.SpriteColor = new Color(ColorR, ColorG, ColorB, ColorA);

                Console.WriteLine("length"+ temp.Length);

                if (temp.Length >= 25)
                {
                    mirror = Convert.ToBoolean(temp[23]);
                }

                if (mirror)
                {
                    box.SetMirror();
                }

                return true;
            };

            return false;
        }

        override public String SaveOut()
        {
            String str;
            if (mirror)
            {
                str = "Sprite " + ClassID + " = PhysicalFactory.SetSpriteOnGameScene(this, " + (int)sprite.Position.X + ", " + (int)sprite.Position.Y + ", " + RotateR + "f, \"" + _resourceName.Split(".".ToCharArray())[0] + "\", new Color(" + sprite.SpriteColor.R + ", " + sprite.SpriteColor.G + ", " + sprite.SpriteColor.B + ", " + sprite.SpriteColor.A + "), true, " + this._layerName.Contains("5").ToString().ToLower() +");//" + _layerName;

            }
            else str = "Sprite " + ClassID + " = PhysicalFactory.SetSpriteOnGameScene(this, " + (int)sprite.Position.X + ", " + (int)sprite.Position.Y + ", " + RotateR + "f, \"" + _resourceName.Split(".".ToCharArray())[0] + "\", new Color(" + sprite.SpriteColor.R + ", " + sprite.SpriteColor.G + ", " + sprite.SpriteColor.B + ", " + sprite.SpriteColor.A + "), false, " + this._layerName.Contains("5").ToString().ToLower() + ");" + "//," + _layerName;

            if (LockAt32)
            {

            }
            else
            {
                str += ", unlock";
            }


            return str;
        }

        override public void SelectedAction()
        {
            Game1.SpriteEditorUIScene.AttachChild(spriteTxt);
        }

        override public void SelectedUpdate()
        {
            if (KeyBoardManager.IsKeyEdgeDown(Keys.Delete)) Delete();

            spriteTxt.Text = "Selected: ";
            spriteTxt.Text += ClassID;
            spriteTxt.Text += "\n Position =" + sprite.Position.ToString();
            spriteTxt.Text += "\n Size =" + Size.ToString();
            spriteTxt.Text += "\n Rotate =" + RotateR.ToString();
            spriteTxt.Text += "\n Color =\n" + sprite.SpriteColor.ToString();
            spriteTxt.Text += "\n Lock32 = " + LockAt32.ToString();
            spriteTxt.Text += "\n " + _resourceName.Split(".".ToCharArray())[0]+".png";


            mirrorButton.Text = "[Mirror : " + mirror.ToString() + "]";

            spriteTxt.Position = new Vector2(spriteTxt.Width / 2, spriteTxt.Height / 2 + 200);

            if (!LockAt32)
            {
                if (KeyBoardManager.IsKeyEdgeDown(Keys.Down))
                {
                    Game1.commandManager.Execute(new MoveCommand(this,new Vector2(0,1)));
                }

                if (KeyBoardManager.IsKeyEdgeDown(Keys.Up))
                {
                    Game1.commandManager.Execute(new MoveCommand(this, new Vector2(0, -1)));
                }

                if (KeyBoardManager.IsKeyEdgeDown(Keys.Right))
                {
                    Game1.commandManager.Execute(new MoveCommand(this, new Vector2(1,0)));
                }

                if (KeyBoardManager.IsKeyEdgeDown(Keys.Left))
                {
                    Game1.commandManager.Execute(new MoveCommand(this, new Vector2(-1, 0)));
                }
            }
        }

        override public void UnSelectedAction()
        {
            Game1.SpriteEditorUIScene.DettachChild(spriteTxt);
        }


        //UI

        override public void UISelectedAction()
        {
            Game1.SpriteEditorUIScene.AttachChild(sprite);
            Game1.SpriteEditorUIScene.AttachChild(spriteTxt);
        }

        override public void UISelectedUpdate()
        {

        }

        override public void UnUISelectedAction()
        {
            Game1.SpriteEditorUIScene.DettachChild(sprite);
            Game1.SpriteEditorUIScene.DettachChild(spriteTxt);
        }

        //UI

        override public Vector2 Position
        {
            get
            {
                if (!LockAt32) return sprite.Position;

                return ProxyPosition;
            }
            set
            {
                     ProxyPosition = value;

                    _positionChecker.UnRegisterPosition(prePosition);
                    PositionInformation info = _positionChecker.SpritePositionTranslation(ProxyPosition, new Vector2(sprite.Width, sprite.Height), sprite.Rotate);
                    prePosition = info.PositionHolder;
                    _positionChecker.RegisterPosition(info.PositionHolder);
                    if (LockAt32) sprite.Position = info.Position;
                    else sprite.Position = value;
            }
        }

        Vector2 ProxyPosition;

        public List<Point> prePosition;

        override public Vector2 Size
        {
            get
            {
                return new Vector2(sprite.Width * sprite.ScaleX, sprite.Height * sprite.ScaleY);
            }
            set
            {
                sprite.ScaleX = value.X / sprite.Width;
                sprite.ScaleY = value.Y / sprite.Height;
            }
        }

        override public float RotateR
        {
            get
            {
                return sprite.Rotate;
            }
            set
            {
                sprite.Rotate = value;
                Position = Position;
            }
        }
    }
}
